/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package cc.gehua.octopus.rpc.common.classloader;

import cc.gehua.octopus.rpc.common.resource.Resource;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.security.PermissionCollection;

/**
 *
 * @author herui
 */
public class RPCServerContext implements Context {

    private PermissionCollection _permissions;
    private String _extraClasspath;
    private ClasspathPattern _systemClasses = null;
    private ClasspathPattern _serverClasses = null;
    private boolean _parentLoaderPriority = false;

   public final static String[] __dftSystemClasses =
    {
        "java.",                            // Java SE classes (per servlet spec v2.5 / SRV.9.7.2)
        "javax.",                           // Java SE classes (per servlet spec v2.5 / SRV.9.7.2)
        "org.xml.",                         // needed by javax.xml
        "org.w3c."                         // needed by javax.xml
    } ;

    // Server classes are classes that are hidden from being
    // loaded by the web application using system classloader,
    // so if web application needs to load any of such classes,
    // it has to include them in its distribution.
    public final static String[] __dftServerClasses =
    {
        "org.objectweb.asm.",               // hide asm used by jetty
        "org.eclipse.jdt.",                // hide jdt used by jetty
        "cc.gehua.octopus."                // hide other jetty classes
    } ;

    @Override
    public Resource newResource(String urlOrPath) throws IOException {
        return Resource.newResource(urlOrPath);
    }

    @Override
    public PermissionCollection getPermissions() {
        return _permissions;
    }

    @Override
    public boolean isSystemClass(String name) {
        if (_systemClasses == null) {
            loadSystemClasses();
        }

        return _systemClasses.match(name);
    }

    @Override
    public boolean isServerClass(String name) {
        if (_serverClasses == null) {
            loadServerClasses();
        }

        return _serverClasses.match(name);
    }

    @Override
    public boolean isParentLoaderPriority() {
        return _parentLoaderPriority;
    }

    @Override
    public String getExtraClasspath() {
        return _extraClasspath; //To change body of generated methods, choose Tools | Templates.
    }

    public void setPermissions(PermissionCollection _permissions) {
        this._permissions = _permissions;
    }

    protected void loadSystemClasses() {
        if (_systemClasses != null) {
            return;
        }

        //look for a Server attribute with the list of System classes
        //to apply to every web application. If not present, use our defaults.
        /*
         Server server = getServer();
         if (server != null)
         {
         Object systemClasses = server.getAttribute(SERVER_SYS_CLASSES);
         if (systemClasses != null && systemClasses instanceof String[])
         _systemClasses = new ClasspathPattern((String[])systemClasses);
         }
         */
        if (_systemClasses == null) {
            _systemClasses = new ClasspathPattern(__dftSystemClasses);
        }
    }

    private void loadServerClasses() {
        if (_serverClasses != null) {
            return;
        }

        // look for a Server attribute with the list of Server classes
        // to apply to every web application. If not present, use our defaults.
        /*
         Server server = getServer();
         if (server != null)
         {
         Object serverClasses = server.getAttribute(SERVER_SRV_CLASSES);
         if (serverClasses != null && serverClasses instanceof String[])
         {
         _serverClasses = new ClasspathPattern((String[])serverClasses);
         }
         }
         */
        if (_serverClasses == null) {
            _serverClasses = new ClasspathPattern(__dftServerClasses);
        }
    }

    public void setSystemClasses(String[] systemClasses) {
        _systemClasses = new ClasspathPattern(systemClasses);
    }

    public void addSystemClass(String classOrPackage) {
        if (_systemClasses == null) {
            loadSystemClasses();
        }

        _systemClasses.addPattern(classOrPackage);
    }

    public void prependSystemClass(String classOrPackage) {
        if (_systemClasses == null) {
            loadSystemClasses();
        }
        _systemClasses.prependPattern(classOrPackage);
    }

    public void addServerClass(String classOrPackage) {
        if (_serverClasses == null) {
            loadServerClasses();
        }

        _serverClasses.addPattern(classOrPackage);
    }

    public void prependServerClass(String classOrPackage) {
        if (_serverClasses == null) {
            loadServerClasses();
        }

        _serverClasses.prependPattern(classOrPackage);
    }

    /* ------------------------------------------------------------ */
    /**
     * Convert URL to Resource wrapper for {@link Resource#newResource(URL)}
     * enables extensions to provide alternate resource implementations.
     *
     * @param url
     * @return
     * @throws java.io.IOException
     */
    public Resource newResource(URL url) throws IOException {
        return Resource.newResource(url);
    }

    /* ------------------------------------------------------------ */
    /**
     * Convert URL to Resource wrapper for {@link Resource#newResource(URL)}
     * enables extensions to provide alternate resource implementations.
     *
     * @param uri
     * @return
     * @throws java.io.IOException
     */
    public Resource newResource(URI uri) throws IOException {
        return Resource.newResource(uri);
    }

    public void setParentLoaderPriority(boolean java2compliant) {
        _parentLoaderPriority = java2compliant;
    }

    public void setServerClasses(String[] serverClasses) {
        _serverClasses = new ClasspathPattern(serverClasses);
    }

    public String[] getServerClasses() {
        if (_serverClasses == null) {
            loadServerClasses();
        }

        return _serverClasses.getPatterns();
    }

    public String[] getSystemClasses() {
        if (_systemClasses == null) {
            loadSystemClasses();
        }

        return _systemClasses.getPatterns();
    }
}
